#!/usr/bin/python3
# -*- coding:utf-8 -*-
""""
@Author: shijianbo
@Email:
@Time: 2023/4/6 16:32
@File: basic.py
"""
import re
import threading
from abc import ABCMeta

from BladeFerm.Lib.Common import logger


class DatabaseUtil(metaclass=ABCMeta):
    def __init(self, *args, **kwargs):
        self.CURSOR = {}
        self.db = None
        self._args = args
        self._kwargs = kwargs

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        for t_id, cursor in self.CURSOR.items():
            cursor.close()
        self.db.close()

    def close_db(self):
        try:
            if self.CURSOR:
                for t_id, cursor in self.CURSOR.items():
                    cursor.close()
            if self.db:
                self.db.close()
            return True
        except Exception as errno:
            logger.warning(f'error：{errno}')
            return False


    def commit(self):
        self.db.commit()

    def roll_back(self):
        self.db.rollback()

    def get_description(self, table_name):
        sql = f'select * from {table_name} where 1=1 limit 1'
        self.cursor.execute(sql)
        self.cursor.fetchall()
        descriptions = self.cursor.description
        field_list = list()
        for i, unit in enumerate(descriptions):
            t_d = {
                'index': i,
                'field_name': unit[0].upper(),     # 字段名称
                'type_code': str(unit[1]),      # 字段类型
                'display_size': unit[2],   # 列的显示大小，以字符为单位
                'internal_size': unit[3],  # 列的存储大小，以字节为单位
                'precision': unit[4],      # 列的精度，数字类型的总位数，包括小数点
                'scale': unit[5],          # 列的小数位数
                'is_null_able': True if unit[6] else False      # 该字段是否运行为空
                }
            field_list.append(t_d)
        logger.info(f'{table_name}\'s description : {field_list}')
        return field_list


    def exec_sql(self, sql):
        logger.debug(f'exec_sql:{sql}')
        result = []
        try:
            self.cursor.execute(sql)
            if sql.lower().startswith('select') and self.cursor.description:
                result_set = self.cursor.fetchall()
                keys = [desc[0].upper() for desc in self.cursor.description]
                if result_set:
                    for row in result_set:
                        result.append(dict(zip(keys, row)))
                else:
                    value_list = [None] * len(keys)
                    result.append(dict(zip(keys, value_list)))
        except Exception as e:
            error_info = f'运行sql： {sql}，错误信息是：{e}'
            logger.error(error_info)
            self.roll_back()
            result.append({'ERROR_INFO': error_info})
        finally:
            if re.match(r"insert|update|delete", sql, re.I):
                self.db.commit()
        return result


    @property
    def cursor(self):
        t_id = threading.get_ident()
        if t_id not in self.CURSOR:
            self.CURSOR[t_id] = self.db.cursor()
        return self.CURSOR[t_id]

    @staticmethod
    def parse_insert_statement(sql):
        if re.match(r'INSERT INTO', sql, re.IGNORECASE):
            return None
        # 正则表达式匹配INSERT语句
        match = re.match(r'INSERT INTO (\w+)\s*\(([^)]+)\) VALUES\s*\(([^)]+)\)', sql, re.IGNORECASE)
        if not match:
            raise ValueError("Invalid INSERT statement")

        # 提取表名和列名
        table = match.group(1)
        columns = match.group(2).split(',')
        # 去除列名两边的空白字符
        columns = [col.strip() for col in columns]

        # 提取值
        values = match.group(3).split(',')
        # 去除值两边的单引号或双引号，并去除值两边的空白字符
        values = [val.strip().strip('\'"') for val in values]
        # 将列名和值组合成字典
        data = dict(zip(columns, values))
        return {'table': table, 'data': data}